home *** CD-ROM | disk | FTP | other *** search
- /*
- SillyMUD Distribution V1.1b (c) 1993 SillyMUD Developement
-
- See license.doc for distribution terms. SillyMUD is based on DIKUMUD
- */
-
- #include <string.h>
- #include <stdio.h>
- #include <ctype.h>
-
- #include "protos.h"
-
-
- #define MAX_MSGS 99 /* Max number of messages. */
- #define MAX_MESSAGE_LENGTH 2048 /* that should be enough */
- #define NUM_BOARDS 3
-
- struct message {
- char *date;
- char *title;
- char *author;
- char *text;
- };
-
- struct board {
- struct message msg[MAX_MSGS+1];
- int number;
- };
-
- static struct board_lock_struct {
- struct char_data *locked_for;
- bool lock;
- } board_lock[NUM_BOARDS];
-
-
- int min_read_level[] = { 0, 51, 1};
- int min_write_level[] = { 1, 51, 1};
- int min_remove_level[] = { 51, 51, 51};
-
- struct board boards[NUM_BOARDS];
- struct board *curr_board;
- struct message *curr_msg;
- extern struct char_data *character_list;
-
- /* This sets the minimum level needed to read/write/look at these boards
- mainly included to enable the creation of a "wizard-only" board */
-
- char save_file[NUM_BOARDS][20] = {
- "mortal.board" , "wiz.board", "skexie.board" };
-
-
- /* These are the binary files in which to save/load messages */
-
- void board_write_msg(struct char_data *ch, char *arg, int bnum);
- int board_display_msg(struct char_data *ch, char *arg, int bnum);
- int board_remove_msg(struct char_data *ch, char *arg, int bnum);
- void board_save_board();
- void board_load_board();
- int board_show_board(struct char_data *ch, char *arg, int bnum);
- int fwrite_string(char *buf, FILE *fl);
-
- /* board.c version 1.2 - Jun 1991 by Twilight.
-
- 1.2 changes:
-
- c Added a board and message structure
- took out all pointers in an effort to insure integrity in memory.
- Added differentiation between minimum read levels and minimum write/remove
- levels.
-
- 1.1 changes:
-
- Major repairs-- now allows multiple boards define at compile-time. Set the
- constants NUM_BOARDS and add the new V-Numbers to the if/then structure directly
- below. Also you must attach the board.c procedure in spec_assign.c as usual.
-
- Log message removals and restrict them to level 15 and above.
- Fixed act message resulting from message removal
- Removed unused procedure "fix_long_desc"
- Added a message to inform others in room of a read in progress
- Added minimum level check for each board
- (defined in array min_board_level[NUM_BOARDS]
-
- */
-
- int board(struct char_data *ch, int cmd, char *arg, struct obj_data *obj, int type)
- {
- static int has_loaded = 0;
- char buf[80];
- int bnum = -1;
- int obj_num;
-
- if (type != PULSE_COMMAND)
- return(FALSE);
-
- if (!ch->desc)
- return(0); /* By MS or all NPC's will be trapped at the board */
-
- if (!has_loaded)
- {
- board_load_board();
- has_loaded = 1;
- }
-
- if (!cmd)
- return(FALSE);
-
- /* Identify which board we're dealing with */
-
- obj_num = (obj->item_number);
- if (obj_num == (real_object(3099))) bnum = 0;
- else if (obj_num == (real_object(3098))) bnum = 1;
- else if (obj_num == (real_object(3097))) bnum = 2;
-
- switch (cmd) {
- case 15: /* look */
- return(board_show_board(ch, arg, bnum));
- case 149: /* write */
- board_write_msg(ch, arg, bnum);
- return 1;
- case 63: /* read */
- return(board_display_msg(ch, arg, bnum));
- case 66: /* remove */
- return(board_remove_msg(ch, arg, bnum));
- default:
- return 0;
- }
- }
-
-
- void board_write_msg(struct char_data *ch, char *arg, int bnum) {
-
- int highmessage;
- char buf[MAX_STRING_LENGTH];
- long ct; /* clock time */
- char *tmstr;
-
- extern struct time_info_data time_info;
- extern char *month_name[];
-
- if ( bnum == -1 ) {
- log("Board special procedure called for non-board object.\r\n");
- send_to_char("This board is not in operation at this time.\n\r", ch);
- return;
- }
-
- curr_board = &boards[bnum];
-
- if (GetMaxLevel(ch) < min_write_level[bnum]) {
- send_to_char("You pick up a quill to write, but realize you're not powerful enough\n\r",ch);
- send_to_char("to submit intelligent material to THIS board.\n\r",ch);
- return;
- }
-
- if ( (curr_board->number) > (MAX_MSGS - 1) ) {
- send_to_char("The board is full already.\n\r", ch);
- return;
- }
-
- /* Check for locks, return if lock is found on this board */
-
- if (board_check_locks(bnum, ch))
- return;
-
- /* skip blanks */
-
- for(; isspace(*arg); arg++);
-
- if (!*arg) {
- send_to_char("The board has now been saved permanently to disk.\n\rTo write a new message, use WRITE followed by a title.\n\r", ch);
- return;
- }
-
- /* Now we're committed to writing a message. Let's lock the board. */
-
- board_lock[bnum].lock = 1;
- board_lock[bnum].locked_for = ch;
-
- /* Lock set */
-
- highmessage = boards[bnum].number;
- curr_msg = &curr_board->msg[++highmessage];
-
- if (!(strcmp("Topic",arg))) {
- curr_msg = &curr_board->msg[0];
- free(curr_msg->title);
- free(curr_msg->text);
- free(curr_msg->author);
- free(curr_msg->date);
- (boards[bnum].number)--;
- }
- curr_msg->title = (char *)malloc(strlen(arg)+1);
- strcpy(curr_msg->title, arg);
- curr_msg->author = (char *)malloc(strlen(GET_NAME(ch))+1);
- strcpy(curr_msg->author, GET_NAME(ch));
- ct = time(0);
- tmstr = (char *)asctime(localtime(&ct));
- *(tmstr + strlen(tmstr) - 1) = '\0';
- sprintf(buf,"%.10s",tmstr);
- curr_msg->date = (char *)malloc(strlen(buf)+1);
- strcpy(curr_msg->date, buf);
- send_to_char("Write your message. Terminate with a @.\n\r\n\r", ch);
- act("$n starts to write a message.", TRUE, ch, 0, 0, TO_ROOM);
-
- /* Take care of free-ing and zeroing if the message text is already
- allocated previously */
-
- if (curr_msg->text)
- free (curr_msg->text);
- curr_msg->text = 0;
-
- /* Initiate the string_add procedures from comm.c */
-
- ch->desc->str = &curr_msg->text;
- ch->desc->max_str = MAX_MESSAGE_LENGTH;
- (boards[bnum].number)++;
- if (boards[bnum].number < 0)
- boards[bnum].number = 0;
- }
-
- int board_remove_msg(struct char_data *ch, char *arg, int bnum) {
-
- /* This should now be fixed so that low level chars can remove armor and such. */
-
- int ind, tmessage;
- char buf[256], number[MAX_INPUT_LENGTH];
-
- one_argument(arg, number);
-
- if (!*number || !isdigit(*number))
- return(0);
-
- if (!(tmessage = atoi(number))) return(0);
-
- if ( bnum == -1 ) {
- log("Board special procedure called for non-board object.\r\n");
- send_to_char("This board is not in operation at this time.\n\r", ch);
- return 1;
- }
-
- curr_board = &boards[bnum];
-
- if (GetMaxLevel(ch) < min_remove_level[bnum]) {
- send_to_char("You try and grab one of the notes of the board but get a nasty\n\r",ch);
- send_to_char("shock. Maybe you'd better leave it alone.\n\r",ch);
- return 1;
- }
-
- if (curr_board->number < 1) {
- send_to_char("The board is empty!\n\r", ch);
- return(1);
- }
-
- if (tmessage < 0 || tmessage > curr_board->number) {
- send_to_char("That message exists only in your imagination..\n\r",
- ch);
- return(1);
- }
-
- /* Check for board locks, return if lock is found */
-
- if (board_check_locks(bnum, ch))
- return(1);
-
- ind = tmessage;
-
- free(curr_board->msg[ind].text);
- free(curr_board->msg[ind].date);
- free(curr_board->msg[ind].author);
- free(curr_board->msg[ind].title);
-
- for ( ; ind < (curr_board->number) ; ind++ )
- curr_board->msg[ind] = curr_board->msg[ind+1];
-
- /* You MUST do this, or the next message written after a remove will */
- /* end up doing a free(curr_board->msg[ind].text) because it's not!! */
- /* Causing strange shit to happen, because now the message has a */
- /* To a memory location that doesn't exist, and if THAT message gets */
- /* Removed, it will destroy what it's pointing to. THIS is the board */
- /* Bug we've been looking for! -=>White Gold<=- */
-
- curr_board->msg[curr_board->number].text = NULL;
- curr_board->msg[curr_board->number].date = NULL;
- curr_board->msg[curr_board->number].author = NULL;
- curr_board->msg[curr_board->number].title = NULL;
-
- curr_board->number--;
-
- send_to_char("Message removed.\n\r", ch);
- sprintf(buf, "%s just removed message %d.", ch->player.name, tmessage);
-
- /* Removal message also repaired */
-
- act(buf, FALSE, ch, 0, 0, TO_ROOM);
- sprintf((buf+strlen(buf)-1)," from board %d.",bnum);
- log(buf); /* Message removals now logged. */
-
- board_save_board(bnum);
- return(1);
- }
-
- char *fix_returns(char *text_string)
- {
- char *localbuf;
- int point=0;
- int point2 = 0;
-
- if (!text_string) {
- CREATE(localbuf,char,2);
- strcpy(localbuf,"\n");
- return(localbuf);
- }
-
- if (!(*text_string)) {
- CREATE(localbuf,char,strlen("(NULL)")+1);
- strcpy(localbuf,"(NULL)");
- return(localbuf);
- }
-
- CREATE(localbuf,char,strlen(text_string));
-
- while(*(text_string+point) != '\0')
- if (*(text_string+point) != '\r') {
- *(localbuf+point2) = *(text_string+point);
- point2++;
- point++;
- }
- else
- point++;
- *(localbuf + point2) = '\0'; /* You never made sure of null termination */
- return(localbuf);
- }
-
- void board_save_board(bnum) {
-
- FILE *the_file;
- int ind;
- char buf[256];
- char *temp_add;
-
- /* We're assuming the board number is valid since it was passed by
- out own code */
-
- curr_board = &boards[bnum];
-
- the_file = fopen(save_file[bnum], "w");
-
- if (!the_file) {
- log("Unable to open/create savefile for bulletin board..\n\r");
- return;
- }
-
- fprintf(the_file," %d ", curr_board->number);
- for (ind = 0; ind <= curr_board->number; ind++) {
- curr_msg = &curr_board->msg[ind];
- fwrite_string(curr_msg->title, the_file);
- fwrite_string(curr_msg->author, the_file);
- fwrite_string(curr_msg->date, the_file);
- fwrite_string((temp_add = fix_returns(curr_msg->text)), the_file);
- free(temp_add);
- }
- fclose(the_file);
- return;
- }
-
- void board_load_board() {
-
- FILE *the_file;
- int ind;
- int bnum;
- char buf[256];
-
- memset(boards, 0, sizeof(boards)); /* Zero out the array, make sure no */
- /* Funky pointers are left in the */
- /* Allocated space */
-
- for ( bnum = 0 ; bnum < NUM_BOARDS ; bnum++ ) {
- board_lock[bnum].lock = 0;
- board_lock[bnum].locked_for = 0;
- }
-
- for (bnum = 0; bnum < NUM_BOARDS; bnum++) {
- boards[bnum].number = -1;
- the_file = fopen(save_file[bnum], "r");
- if (!the_file) {
- sprintf(buf,"Can't open message file for board %d.\n\r",bnum);
- log(buf,0);
- continue;
- }
-
- fscanf( the_file, " %d ", &boards[bnum].number);
- if (boards[bnum].number < 0 || boards[bnum].number > MAX_MSGS ||
- feof(the_file)) {
- log("Board-message file corrupt, nonexistent, or empty.\n\r");
- boards[bnum].number = -1;
- fclose(the_file);
- continue;
- }
-
- curr_board = &boards[bnum];
-
- for (ind = 0; ind <= curr_board->number; ind++) {
- curr_msg = &curr_board->msg[ind];
- curr_msg->title = (char *)fread_string (the_file);
- curr_msg->author = (char *)fread_string (the_file);
- curr_msg->date = (char *)fread_string (the_file);
- curr_msg->text = (char *)fread_string (the_file);
- }
- fclose(the_file);
- }
- }
-
- int board_display_msg(struct char_data *ch, char *arg, int bnum)
- {
- char buf[512], number[MAX_INPUT_LENGTH], buffer[MAX_STRING_LENGTH];
- int tmessage;
-
- one_argument(arg, number);
-
- if (!*number || !isdigit(*number))
- return(0);
-
- if (!(tmessage = atoi(number))) return(0);
-
- curr_board = &boards[bnum];
-
- if ((boards[bnum].number != -1) &&
- (tmessage >= 0 && tmessage <= curr_board->number) &&
- (GetMaxLevel(ch) < min_read_level[bnum]) &&
- (strcmp(GET_NAME(ch), curr_board->msg[tmessage].author))) ;
- else
- if ( GetMaxLevel(ch) < min_read_level[bnum] ) {
- send_to_char("You try and look at the messages on the board but you\n\r",
- ch);
- send_to_char("cannot comprehend their meaning.\n\r\n\r",ch);
- act("$n tried to read the board, but looks bewildered.",TRUE,ch, 0, 0,
- TO_ROOM);
- return(1);
- }
-
- if (boards[bnum].number == -1) {
- send_to_char("The board is empty!\n\r", ch);
- return(1);
- }
-
- if (tmessage < 0 || tmessage > curr_board->number) {
- send_to_char("That message exists only in your imagination..\n\r",ch);
- return(1);
- }
-
- curr_msg = &curr_board->msg[tmessage];
-
- sprintf(buf, "$n reads message %d titled : %s.",tmessage, curr_msg->title);
- act(buf, TRUE, ch, 0, 0, TO_ROOM);
- sprintf(buffer, "Message %2d (%s): %-15s -- %s", tmessage, curr_msg->date, curr_msg->author, curr_msg->title );
- sprintf(buffer + strlen(buffer), "\n\r----------\n\r%s", (curr_msg->text?curr_msg->text:"(null)"));
- page_string(ch->desc, buffer, 1);
- return(1);
- }
-
- int board_show_board(struct char_data *ch, char *arg, int bnum)
- {
- int i;
- char buf[MAX_STRING_LENGTH], tmp[MAX_INPUT_LENGTH];
-
- one_argument(arg, tmp);
-
- if (!*tmp || !isname(tmp, "board bulletin"))
- return(0);
-
- if ((GetMaxLevel(ch) < min_read_level[bnum]) && (bnum !=5))
- /* Skip if board 5 (Reimb board) */
- {
- send_to_char("You try and look at the messages on the board but you\n\r",ch);
- send_to_char("cannot comprehend their meaning.\n\r",ch);
- act("$n tried to read the board, but looks bewildered.",TRUE,ch, 0, 0, TO_ROOM);
- return(1);
- }
-
- curr_board = &boards[bnum];
-
- act("$n studies the board.", TRUE, ch, 0, 0, TO_ROOM);
-
- strcpy(buf,"This is a bulletin board. Usage: READ/REMOVE <messg #>, WRITE <header>\n\r");
- if (boards[bnum].number == -1)
- strcat(buf, "The board is empty.\n\r");
- else {
- sprintf(buf + strlen(buf), "There are %d messages on the board.\n\r",
- curr_board->number);
- sprintf(buf + strlen(buf), "\n\rBoard Topic:\n\r%s------------\n\r",curr_board->msg[0].text);
- for ( i = 1 ; i <= curr_board->number ; i++ )
- /* if (((GET_MAX_LEVEL(ch) < min_read_level[bnum]) &&
- (strcmp(ch->name, curr_board->msg[i].author))) ||
- (GET_MAX_LEVEL(ch) >= min_read_level[bnum])) */
- sprintf(buf + strlen(buf), "%-2d : %-15s (%s) -- %s\n\r", i ,
- curr_board->msg[i].author, curr_board->msg[i].date,
- curr_board->msg[i].title);
- }
- page_string(ch->desc, buf, 1);
- return(1);
- }
-
- int fwrite_string (char *buf, FILE *fl)
- {
- return (fprintf(fl, "%s~\n", buf));
- }
-
- int board_check_locks (int bnum, struct char_data *ch) {
-
- char buf[MAX_INPUT_LENGTH];
- struct char_data *tmp_char;
- bool found = FALSE;
- if (!board_lock[bnum].lock) return(0);
-
- /* FIRST lets' see if this character is even in the game anymore! -WG-*/
- for (tmp_char = character_list; tmp_char; tmp_char = tmp_char->next)
- {
- if (tmp_char == board_lock[bnum].locked_for)
- {
- found = TRUE;
- break;
- }
- }
- if (!found)
- {
- log("Board: board locked for a user not in game.");
- board_lock[bnum].lock = 0;
- board_lock[bnum].locked_for = NULL;
- return(0);
- }
-
- /* Check for link-death of lock holder */
-
- if (!board_lock[bnum].locked_for->desc) {
- sprintf(buf,"You push %s aside and approach the board.\n\r",board_lock[bnum].locked_for->player.name);
- send_to_char(buf, ch);
- }
-
- /* Else see if lock holder is still in write-string mode */
-
- else if (board_lock[bnum].locked_for->desc->str) { /* Lock still holding */
- sprintf(buf,"You try to approach the board but %s blocks your way.\n\r",board_lock[bnum].locked_for->player.name);
- send_to_char(buf, ch);
- return (1);
- }
-
- /* Otherwise, the lock has been lifted */
-
- board_save_board(bnum);
- board_lock[bnum].lock = 0;
- board_lock[bnum].locked_for = 0;
- return(0);
- }
-
-